package com.fpx.open.platform.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 时间Util工具类
 * @author sunkey
 * @date Mar 27, 2013 11:38:24 AM
 * @version 1.0.0 
 * @copyright fpx.com 
 */
public class DateUtil {

	private final static Logger logger = LoggerFactory
			.getLogger(DateUtil.class);

	public final static String DATE_FORMAT_S = "yyyy-MM-dd HH:mm:ss";
	
	public final static String DATE_FORMAT = "yyyy-MM-dd";

	public final static String TIMESTAMP = "yyyyMMddHHmmss";

	protected static SimpleDateFormat initSimpleDateFormat(
			String format) {
		return new SimpleDateFormat(format);
	}

	public static String formatForCurrent(String fomat) {
		Date date = new Date();
		DateFormat df = DateUtil.initSimpleDateFormat(fomat);
		df.setLenient(false);
		return df.format(date);
	}

	public static Date parse(String time, String format) {
		try {
			DateFormat df = DateUtil.initSimpleDateFormat(format);
			df.setLenient(false);
			return df.parse(time);
		} catch (ParseException e) {
			logger.error("时间格式转换异常", e);
			return null;
		}
	}

	public static String format(Date time, String format) {
		DateFormat df = DateUtil.initSimpleDateFormat(format);
		df.setLenient(false);
		return df.format(time);
	}

	public static int getIntervalSecond(String startTime, String endTime) {
		try {
			DateFormat df = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
			Date startTimeDate = df.parse(startTime);
			Date endTimeDate = df.parse(endTime);
			int sec = (int) (startTimeDate.getTime() - endTimeDate.getTime()) / 1000;
			return sec;
		} catch (ParseException e) {
			logger.error("DateUtil.getSecond方法出错", e);
			return 0;
		}
	}

	public static int getIntervalSecond(Date startTime, Date endTime) {
		return (int) (startTime.getTime() - endTime.getTime()) / 1000;
	}

	/**
	 * 时间time减去overlapSecond秒后的时间
	 * 
	 * @param time
	 * @param overlapSecond
	 * @return
	 * @throws Exception
	 */
	public static String getStartTimeByTime(String time, String overlapSecond) {
		try {
			DateFormat df = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
			Date date = df.parse(time);
			// time时间的毫秒数
			long timeMillisecond = date.getTime();
			// 30秒的毫秒数
			long overlapMillisecond = Integer.valueOf(overlapSecond) * 1000;
			// 减去30秒后的时间
			Date startTime = new Date(timeMillisecond - overlapMillisecond);
			return df.format(startTime);

		} catch (ParseException e) {
			logger.error("时间time减去overlapSecond秒后的时间出错", e);
			return null;
		}
	}

	/**
	 * 时间time加上intervalTime分钟后的时间
	 * 
	 * @param time
	 * @param intervalTime
	 * @return
	 */
	public static String getEndTimeByTime(String time, String intervalTime) {
		try {
			DateFormat df = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
			Date date = df.parse(time);
			// time时间的毫秒数
			long timeMillisecond = date.getTime();
			// 25分钟的毫秒数
			long intervalMillisecond = Integer.valueOf(intervalTime) * 60 * 1000;
			// 加上25分钟后的时间
			Date endTime = new Date(timeMillisecond + intervalMillisecond);
			return df.format(endTime);
		} catch (ParseException e) {
			logger.error("时间time加上intervalTime分钟后的时间出错", e);
			return null;
		}
	}

	/**
	 * 
	 * 获取时间，N为负数：则返回当前时间的n个小时之前的时间，如果为正数，则返回当前时间n个小时之后的时间
	 * 
	 * @return
	 */
	public static String getTimeByHour(int hours) {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		DateFormat sdf = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
		sdf.setTimeZone(TimeZone.getDefault());
		now.add(Calendar.HOUR_OF_DAY, hours);
		return (sdf.format(now.getTime()));
	}

	/**
	 * 获取时间，往hours向前或向后推n小时
	 * 
	 * @param time
	 * @param day
	 * @return
	 */
	public static String getBallanceTimeByHours(String time, int hours) {
		try {
			DateFormat sdf = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
			Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
			calendar.setTime(sdf.parse(time));

			sdf.setTimeZone(TimeZone.getDefault());
			calendar.add(Calendar.HOUR_OF_DAY, hours);

			return (sdf.format(calendar.getTime()));
		} catch (ParseException e) {
			logger.error("时间转换出错", e);
			return "";
		}
	}

	/**
	 * 获取时间，往day向前或向后推n天
	 * 
	 * @param time
	 * @param day
	 * @return
	 */
	public static String getBallanceTimeByDay(String time, int day) {
		try {
			DateFormat sdf = DateUtil.initSimpleDateFormat(DATE_FORMAT_S);
			Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
			calendar.setTime(sdf.parse(time));

			sdf.setTimeZone(TimeZone.getDefault());
			calendar.add(Calendar.DAY_OF_YEAR, day);

			return (sdf.format(calendar.getTime()));
		} catch (ParseException e) {
			logger.error("时间转换出错", e);
			return "";
		}
	}

	/**
	 * 字符串是否为空
	 * 
	 * @param str
	 * @return
	 */
	private static boolean isNULL(String str) {
		return (null == str || str.trim().equals(""));
	}

	/**
	 * 判断是否为合法的日期时间字符串
	 * 
	 * @param str_input
	 * @return boolean;符合为true,不符合为false
	 */
	public static boolean isDate(String str_input, String rDateFormat) {
		if (!isNULL(str_input)) {
			SimpleDateFormat formatter = new SimpleDateFormat(rDateFormat);
			formatter.setLenient(false);
			try {
				formatter.format(formatter.parse(str_input));
			} catch (ParseException e) {
				logger.error("判断是否为合法的日期时间字符串", e);
				return false;
			}
			return true;
		}
		return false;

	}

	/**
	 * 格式化当前时间
	 * 
	 * @param dateFormat
	 * @return
	 */
	public static String getCurrTime(String dateFormat) {
		Date d = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
		return formatter.format(d);
	}

	/**
	 * 如果结束日期在起始日期之前，则返回false;
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static boolean compareDate(String startDate, String endDate) {
		SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
		try {
			Date d1 = formatter.parse(startDate);
			Date d2 = formatter.parse(endDate);

			if (d2.before(d1)) {
				return false;
			}
		} catch (ParseException e) {
			logger.error("判断结束日期在起始日期之前异常错误", e);
			return false;
		}
		return true;
	}

	/**
	 * 判断结束日期与起始日期的日期天数差
	 * @param firstDate
	 * @param endDate
	 * @return
	 * @throws ParseException
	 */
	public static int subtractDay(String firstDate, String endDate) {
		DateFormat df = new SimpleDateFormat(DATE_FORMAT);
		try {
			Date d1 = df.parse(firstDate);
			Date d2 = df.parse(endDate);
			int date = (int) ((d2.getTime() - d1.getTime()) / 86400000);
			return date;
		}
		catch(ParseException e) {
			logger.error("判断结束日期与起始日期的日期天数差错误异常", e);
			return 0;
		}
	}
	
	/**
	 * 如果结束时间在起始时间之前，则返回false;
	 * 
	 * @param startTime
	 * @param endTime
	 * @param format  "yyyy-MM-dd'T'HH:mm:ss"
	 * @return
	 */
	public static boolean compareTime(String startTime, String endTime, String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		try {
			Date d1 = formatter.parse(startTime);
			Date d2 = formatter.parse(endTime);
			
			if (d2.before(d1)) {
				return false;
			}
		} catch (ParseException e) {
			logger.error("判断结束时间在起始时间之前异常错误", e);
			return false;
		}
		return true;
	}
	
	/**
	 * <p>获取时间，并加上hours小时</p>
	 * <p>hours可以为负数</p>
	 * 
	 * @param date
	 * @param hours
	 * @return
	 */
	public static Date getTimePreAddHours(Date date, int hours) {
		Calendar cal = Calendar.getInstance(TimeZone.getDefault());
		cal.setTime(date);
		cal.add(Calendar.HOUR_OF_DAY, hours);
		return cal.getTime();
	}
	
	/**
	 * <p>比较时间</p>
	 * <p>end>start = true</p>
	 * <p>start>end = false</p>
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static boolean compareTime(Date start, Date end) {
		if (start == null || end == null)
			return false;
		if (end.before(start))
			return false;
		return true;
	}
	/**
	 * 获取当前系统时间
	 * @param format  "yyyy-MM-dd HH:mm:ss"
	 * @return
	 */
    public static String getStandardSysdate(){
    	Date objDate = new Date();
    	SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT_S);
    	return formatter.format(objDate);
    }
    
    
    /**
     * 在指定日期上添加天数
     * 
     * @param date
     * @param n 天数
     * @return
     */
    public static Date add(Date date, int n) {
        if (date == null)
            return null;
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.DATE, n);
        return gc.getTime();
    }
}
